package com.pig4cloud.pig.village.land.service.impl;

import cn.hutool.core.bean.BeanUtil;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.pig4cloud.pig.village.api.dto.LandDTO;
import com.pig4cloud.pig.village.api.dto.LandTotalDTO;
import com.pig4cloud.pig.village.api.entity.Land;
import com.pig4cloud.pig.village.api.entity.Team;
import com.pig4cloud.pig.village.api.entity.Villager;
import com.pig4cloud.pig.village.land.mapper.LandMapper;
import com.pig4cloud.pig.village.land.service.ILandService;
import com.pig4cloud.pig.village.team.service.ITeamService;
import com.pig4cloud.pig.village.villager.service.IVillagerService;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;

/**
 * @author limbray.li
 * @date 2021/6/19
 */
@Service
@RequiredArgsConstructor
public class LandServiceImpl extends ServiceImpl<LandMapper, Land> implements ILandService {
	@Resource
	private IVillagerService villagerService;
	@Resource
	private ITeamService teamService;
	@Resource
	private LandMapper landMapper;

	@Override
	public IPage<LandDTO> selectForPage(Page page, Long teamId, Long villagerId) {
		LambdaQueryWrapper<Land> query = Wrappers.lambdaQuery();
		query.eq(teamId != null, Land::getTeamId, teamId);
		query.eq(villagerId != null, Land::getVillagerId, villagerId);
		IPage<Land> pages = super.page(page, query);
		Map<Long, Villager> villagerMap = getVillagerMap(pages.getRecords());
		Map<Long, String> teamNameMap = getTeamNameMap(pages.getRecords());
		IPage<LandDTO> result = pages.convert(e -> landConvert(e, villagerMap, teamNameMap));
		return result;
	}

	private Map<Long, Villager> getVillagerMap(List<Land> list) {
		List<Long> villagerIds = list.stream().map(Land::getVillagerId).collect(Collectors.toList());
		if (CollectionUtils.isEmpty(villagerIds)) {
			return null;
		}
		List<Villager> villagers = villagerService.listByIds(villagerIds);
		Map<Long, Villager> villagerMap = villagers.stream().collect(Collectors.toMap(Villager::getId, Function.identity()));
		return villagerMap;
	}

	private Map<Long, String> getTeamNameMap(List<Land> list) {
		List<Long> teamIds = list.stream().map(Land::getTeamId).collect(Collectors.toList());
		if (CollectionUtils.isEmpty(teamIds)) {
			return null;
		}
		List<Team> teams = teamService.listByIds(teamIds);
		Map<Long, String> teamNameMap = teams.stream().collect(Collectors.toMap(Team::getId, Team::getTeamName));
		return teamNameMap;
	}

	private LandDTO landConvert(Land e, Map<Long, Villager> villagerMap, Map<Long, String> teamNameMap) {
		LandDTO dto = new LandDTO();
		BeanUtil.copyProperties(e, dto);
		Villager v = null;
		String teamName = "";
		if (villagerMap != null) {
			villagerMap.get(e.getVillagerId());
		}
		if (teamNameMap != null) {
			teamName = teamNameMap.get(e.getTeamId());
		}
		if (v != null) {
			dto.setVillagerName(v.getName());
		}
		dto.setTeamName(teamName);
		dto.setTotal(landAdd(dto.getLandE(),dto.getLandG()));
		return dto;
	}


	@Override
	public LandDTO getDtoById(Long id) {
		Land land = super.getById(id);
		Villager v = villagerService.getById(land.getVillagerId());
		Team team = teamService.getById(land.getTeamId());
		LandDTO dto = new LandDTO();
		BeanUtil.copyProperties(v, dto);
		if (v != null) {
			dto.setVillagerName(v.getName());
		}
		dto.setTeamName(team.getTeamName());
		dto.setTotal(landAdd(dto.getLandE(),dto.getLandG()));
		return dto;
	}

	@Override
	public List<LandTotalDTO> teamTotal(Long teamId) {
		List<LandTotalDTO> result = new ArrayList<>();
		if (teamId != null) {
			Team team = teamService.getById(teamId);
			LandTotalDTO dto = landMapper.oneTotal(teamId);
			dto.setType("team");
			dto.setName(team.getTeamName());
			dto.setTotal(landAdd(dto.getLandE(),dto.getLandG()));
			result.add(dto);
		} else {
			result = landMapper.groupTotal();
			result.forEach(e -> {
				e.setType("team");
				e.setTotal(landAdd(e.getLandE(),e.getLandG()));
			});
		}
		return result;
	}

	@Override
	public LandTotalDTO villageTotal() {
		LandTotalDTO dto = landMapper.oneTotal(null);
		dto.setType("village");
		dto.setName("all");
		dto.setTotal(landAdd(dto.getLandE(),dto.getLandG()));
		return dto;
	}

	public static BigDecimal landAdd(BigDecimal a, BigDecimal b) {
		a = a == null ? new BigDecimal("0") : a;
		b = b == null ? new BigDecimal("0") : b;
		return a.add(b);
	}
}
